﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>

#include "common.h"

// 常见的关键字
/* short signed union signed unsigned都是关键字，void while
auto break case char const都是关键字， continue default do double else enum static struct都是结构体
extern声明外部变量， float for goto if int long register都是寄存器关键字 return sizeof switch  while 
typedef声明类型 union声明结构体 void非法，一个函数的返回类型，参数类型 volatile学习*/
// 注意变量名不能关键字
// 注意 define 是关键字，表示一个预定义值，编译器会替换
typedef unsigned int 无符号整型;  // 声明一个类型 无符号整型 代表 unsigned int; 注意 无符号整型 只能声明为类型，不能声明为变量，使用 typedef 只能替换类型

// 声明外部变量的 关键字 extern
extern int g_gal;
extern int g_in_gal; // 由于 static 导致静态变量失效
extern int add(int a, int b); // 声明一个外部函数的原型
extern int mul(int x, int y); // 由于 static 导致函数失效导致外部函数声明

// #define 声明一个标识宏
#define NUM 1000 // NUM表示一个宏值为 1000，注意宏没有类型
#define MUL(x,y) x*y  // 注意书写 严谨书写为: MUL(x,y) ((x)*(y))
// 一个宏 MUL 表示函数名，x, y 表示参数类型，x*y 代表返回值，宏展开为x*y
static void study12_test()
{
	static int num1 = 0;  // 使用 static 关键字 使得 num1 成静态局部变量，存储在静态存储区
	// 运行程序过程中，记录当前 num1 的值
	/* 1.static 关键字使得全局变量时，全局变量全局存在，
	全局变量全局存在时，不能修改全局变量的存储位置，存储在静态存储区
	静态存储区的全局变量全局存在时，存储的初始值为0
	全局变量全局存在时，static使得全局变量全局存在，全局变量只能声明一次 */
	num1++;  // 注意使用局部变量时，修改内存中的数值
	printf("%d\t", num1);
}

void study12()
{
	auto int a = 10; // 可以省略 auto 关键字
	printf("输出的\n");
	// 使用 typedef 关键字声明类型
	无符号整型 b = 100; // 等价于 unsigned int b = 100; 表示非法 b = 100
	printf("输出b的值为：%d\n", b);
	// static 全局变量和静态局部变量
	int i1 = 0;
	while (i1 < 10)
	{
		study12_test();
		i1++;
	}

	// 静态全局变量和静态局部变量的区别，静态全局变量只能在定义它的文件中访问
	/* 静态全局变量在定义它的文件之外的文件中不能被访问
	资源文件 .c .cpp等通常不使用静态全局变量 */
	printf("\n全局变量g_gal的值为：%d\n", g_gal);
	// printf("全局变量g_in_gal的值为：%d\n", g_in_gal); // 错误
	// 静态局部变量
	printf("函数add的结果为：%d\n", add(a, b)); // -> 110
	// printf("函数mul的结果为：%d\n", mul(a, b)); // 错误

	// 寄存器关键字 register 建议编译器将变量存储在寄存器中而不是内存中
	register int impro = 5; // 希望变量 5 存储在寄存器中，而不是内存中

	// 宏定义常量的使用
	printf("NUM的值为：%d\n", NUM);
	int n1 = NUM;
	int arr1[NUM] = { 1, 2 };
	printf("n1的值为：%d，arr1的第二个元素：%d\n", n1, arr1[1]);

	// 宏定义函数的使用
	int x1 = 8;
	int y1 = 5;
	printf("宏定义函数的结果为：%d\n", MUL(x1, y1)); // 注意：宏定义函数的参数不进行类型检查
	//return 0;
}